package org.example.springchatroom.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.example.springchatroom.component.OnlineUserManager;
import org.example.springchatroom.constants.Constants;
import org.example.springchatroom.mapper.MessageMapper;
import org.example.springchatroom.mapper.MessageSessionMapper;
import org.example.springchatroom.mapper.UserMapper;
import org.example.springchatroom.model.*;
import org.example.springchatroom.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 九转苍翎
 * Date: 2025/9/15
 * Time: 13:49
 */
@Component
@Slf4j
public class TextWebSocketController extends TextWebSocketHandler {

    @Autowired
    private OnlineUserManager onlineUserManager;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MessageSessionMapper messageSessionMapper;
    @Autowired
    private MessageMapper messageMapper;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        log.info("建立连接");
        String token = (String)session.getAttributes().get(Constants.REQUEST_HEADER_TOKEN);
        Integer userId = JwtUtils.getIdByToken(token);
        log.info("afterConnectionEstablished解析token,userId:{}", userId);
        if (userId == null) {
            return;
        }
        onlineUserManager.online(userId,session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        log.info("接收消息,message:{}", message.toString());
        String token = (String)session.getAttributes().get(Constants.REQUEST_HEADER_TOKEN);
        Integer userId = JwtUtils.getIdByToken(token);
        log.info("handleTextMessage解析token,userId:{}", userId);
        if (userId == null) {
            log.info("handleTextMessage用户未登录");
            return;
        }
        String content = message.getPayload();
        MessageRequest request = objectMapper.readValue(content, MessageRequest.class);
        if (request.getType().equals("message")){
            transferMessage(userId,request);
        }else {
            log.error("message.type有误,type:{}", request.getType());
        }
    }

    private void transferMessage(Integer userId, MessageRequest request) throws IOException {
        User user = userMapper.getUserById(userId);
        MessageResponse response = new MessageResponse();
        response.setFromId(userId);
        response.setFromName(user.getUserName());
        Integer sessionId = request.getSessionId();
        response.setSessionId(sessionId);
        response.setContent(request.getContent());
        String responseJson = objectMapper.writeValueAsString(response);
        //1.根据request.sessionId查询当前会话有哪些用户
        List<Friend> friendList = messageSessionMapper.getFriendListBySessionId(sessionId, userId);
        Friend friend = new Friend();
        friend.setFriendId(userId);
        friend.setFriendName(user.getUserName());
        friendList.add(friend);
        //2.遍历用户列表,给每个用户发消息。根据userId还能在onlineUserManager中查询到对应的WebSocketSession
        for (Friend curFriend : friendList) {
            WebSocketSession curSession = onlineUserManager.getSession(curFriend.getFriendId());
            if (curSession == null) {
                continue;
            }
            curSession.sendMessage(new TextMessage(responseJson));
        }
        //3.将消息保存到数据库
        Message message = new Message();
        message.setSessionId(sessionId);
        message.setFromId(userId);
        message.setContent(request.getContent());
        messageMapper.addMessage(message);
        log.info("保存消息,message:{}", message);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) {
        log.info("发生异常,exception:{}", exception.toString());
        String token = (String)session.getAttributes().get(Constants.REQUEST_HEADER_TOKEN);
        Integer userId = JwtUtils.getIdByToken(token);
        log.info("handleTransportError解析token,userId:{}", userId);
        if (userId == null) {
            return;
        }
        onlineUserManager.offline(userId,session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        log.info("断开连接,status:{}", status.toString());
        String token = (String)session.getAttributes().get(Constants.REQUEST_HEADER_TOKEN);
        Integer userId = JwtUtils.getIdByToken(token);
        log.info("afterConnectionClosed解析token,userId:{}", userId);
        if (userId == null) {
            return;
        }
        onlineUserManager.offline(userId,session);
    }
}
